#ifndef DOMINATOR_TREE_H
#define DOMINATOR_TREE_H
#include "../../include/ir.h"
#include "../pass.h"
#include <set>
#include <vector>

class DominatorTree {
public:
    CFG *C;
    std::vector<std::vector<LLVMBlock>> dom_tree{};
    std::vector<LLVMBlock> idom{};//直接支配节点。
    std::vector<std::vector<int>> df;//存储每个节点的支配边界
    std::vector<std::vector<int>> Dom;  // 存储每个节点的直接支配节点列表Dom[u][v] 表示 v 是否直接支配 u
    std::vector<std::vector<bool>> dom; // 支配关系矩阵，dom[u][v] 表示 v 是否支配 u
    std::vector<std::vector<int>> pre; // 每个结点的前驱结点列表
    std::vector<int> ord;              // 图的逆后序排列
    std::vector<int> idom_int;//直接支配节点,目前是废的不要用
    std::vector<std::vector<int>> e;    // 边集合
    void BuildDominatorTree(bool reverse = false);    // build the dominator tree of CFG* C
    std::set<int> GetDF(std::set<int> S);             // return DF(S)  S = {id1,id2,id3,...}
    std::set<int> GetDF(int id);                      // return DF(id)
    bool IsDominate(int id1, int id2);                // if blockid1 dominate blockid2, return true, else return false
    void getdom();
    void getidom();//这个函数也是废的不要用
    void initialize();
    void BuildDomTree();//这个函数也是废的不要用
    void PrintDomTree() const;
    void PrintIdom() const;//这个函数由于用的是idom所以也是废的不要用
    void PrintDF() const;
    void PrintDom() const;
    void printdom() const;
    void PrintDomMatrix() const;
    void PrintPredecessors() const;
    void PrintOrder() const;
    void PrintIdomInt() const;//这个函数也是废的不要用
    void PrintEdges() const;
    void PrintBlock(const LLVMBlock& block) const;
    void initialize_idom();
    void build_dom_tree();
    
    // TODO(): add or modify functions and members if you need
};

class DomAnalysis : public IRPass {
private:
    std::map<CFG *, DominatorTree> DomInfo;

public:
    DomAnalysis(LLVMIR *IR) : IRPass(IR) {}
    void Execute();
    DominatorTree *GetDomTree(CFG *C) { return &DomInfo[C]; }
    // TODO(): add more functions and members if you need
};
#endif